import re
from dataclasses import dataclass

import yaml


@dataclass  # 将数据转为类对象，转换过程自动校验
class CaseInfo:
    """
    对yaml用例进行建模
    模型内容：字段名、类型
    模型用于校验数据格式是否符合，该有的字段是否都有
    """
    name: str  # 用例名
    request: dict  # 请求内容
    extract: dict  # 需要提取的内容
    validate: dict  # 断言内容
    # 有默认值则允许在yaml中不写
    order: int = 0  # 根据值排序
    parametrize: list = None  # 数据驱动，用于拆分多个用例
    flow_lise: list = None  # 流程列表
    feature: str = '默认项目'
    story: str = '默认功能'

def verify_case(data):
    """验证数据是否符合建模"""
    # 注意：python是动态类型，所以只会检查字段，不检查类型
    case = CaseInfo(**data)  # 实例化，转换，校验
    return case


def ddt_case(data):
    """数据驱动：根据parametrize字段内容，动态生成多个用例"""
    ddt_case_list = []
    parametrize = data.pop('parametrize')  # pop方式取出数据
    key_list = parametrize[0]  # [a,b,c]
    value_list = parametrize[1:]  # [[1,2,3],[11,22,33],[111,222,333]]

    for value in value_list:
        var_dict = dict(zip(key_list, value))  # {a:1, b:2, c:3}
        # yaml转字符串
        data_str = yaml.safe_dump(data)
        # 替换${变量}
        var_name_list = re.findall(r"\${(.*?)}", data_str)  # "a=${a}, b=${b}, c=${c}" => [a,b,c]
        for var_name in var_name_list:
            if var_name in var_dict:  # b in {a:1, b:2, c:3}
                data_str = data_str.replace("${" + var_name + "}", str(var_dict[var_name]))
        # 字符串转yaml
        new_data = yaml.safe_load(data_str)
        new_case = CaseInfo(**new_data)
        ddt_case_list.append(new_case)

    return ddt_case_list


def flow_case(flow_list):
    """流程用例"""
    case = CaseInfo(**flow_list[0])  # 读取name等不重复的数据
    case.flow_lise = []

    for flow in flow_list:  # 读取重复内容
        temp_case = CaseInfo(
            name=case.name,  # case是python对象，可以用点；flow是字典所以需要用dict的方式取值
            request=flow['request'],
            extract=flow['extract'],
            validate=flow['validate']
        )

        case.flow_lise.append(temp_case)

    return case
